
#include <stdio.h> 
#include <stdlib.h>
#include <sys/types.h>
#include <sys/msg.h>
#include <sys/ipc.h>
#include <sys/wait.h>
#include <unistd.h>
#include <sys/shm.h>
#include <pthread.h>  
#include <semaphore.h>  

// #define MSGKEY 75          /*定义关键词MEGKEY*/
// struct msgform                /*消息结构*/
// {
// 	long mtype;
// 	char mtexe[100];         /*文本长度*/
// }msg;
// int msgqid,i;

// void CLIENT()
// {
// 	int i;
// 	msgqid=msgget(MSGKEY,0777|IPC_CREAT);
// 	for(i=10;i>=1;i--)
// 	{
// 		 msg.mtype=i;
// 		 printf("(client)sent\n");
//  		 msgsnd(msgqid,&msg,1030,0);       /*发送消息msg入msgid消息队列*/
// 	}
// 	exit(0);
// }

// void SERVER()
// { 
//     msgqid=msgget(MSGKEY,0777|IPC_CREAT); /*由关键字获得消息队列*/
//     do
//     {
//         msgrcv(msgqid,&msg,1030,0,0);  /*从队列msgid接受消息msg*/
//         printf("(server)receive\n");
//     }
//     while(msg.mtype!=1);             /*消息类型为1时，释放队列*/
//     {
//         msgctl(msgqid, IPC_RMID,0);
//     }

// }

// int main()
// {
//     if(fork()) 
//     {
//         SERVER();
//         wait(0);
//     }
// 	else 
//     {
//         CLIENT();
//     }
//     return 0;
// }


// #define SHMKEY  75                   /*定义共享区关键词*/
// int shmid,i;
// int *addr;

// void CLIENT()
// {	
// 	int i;	
// 	shmid=shmget(SHMKEY,1024, 0777|IPC_CREAT);    /*获取共享区，长度1024，关键词SHMKEY*/
// 	addr=shmat(shmid,0,0);                /*共享区起始地址为addr*/	
// 	for(i=9;i>=0;i--) 	
// 	{		
// 		while(*addr!= -1);                  		
// 		printf("(client)sent\n");                 /*打印（client）sent*/		
// 		*addr=i;                             /*把i赋给addr*/	
// 	}	
// 	exit(0);
// }

// void SERVER()
// { 	
// 	do	
// 	{	
// 		while(*addr ==-1);
//         {	
// 		    printf("(server)received\n%d",*addr);               /*服务进程使用共享区*/	
//         }
//         if(*addr!=0)
//         {
//             *addr=-1;
//         }	
// 	}while(*addr);	
//     wait(0);
//     shmctl(shmid,IPC_RMID,0);	
// }

// int main()
// {	
// 	shmid=shmget(SHMKEY,1024,0777|IPC_CREAT);  /*创建共享区*/	
// 	addr=shmat(shmid,0,0);                         /*共享区起始地址为addr*/	
//     *addr=-1;	
// 	if(fork())
// 	{
// 	    SERVER();	
// 	}
// 	else
// 	{
// 	    CLIENT();	
// 	}
//     return 0;
//  }
  
#define BUFFER_SIZE 1  
  
// 缓冲区  
int buffer[BUFFER_SIZE];  
int in = 0; // 缓冲区输入位置  
int out = 0; // 缓冲区输出位置  
  
// 信号量  
semaphore_t empty; // 缓冲区是否为空  
semaphore_t full;  // 缓冲区是否已满  
  
// 数据采集任务  
void* data_collection_task(void* arg) {  
    while (1) {  
        // 模拟数据采集  
        int data = rand() % 100; // 假设我们采集一个0-99的整数  
  
        // 等待缓冲区为空  
        sem_wait(&empty);  
  
        // 向缓冲区写入数据  
        buffer[in] = data;  
        printf("Collected data: %d\n", data);  
  
        // 更新输入位置并处理环绕  
        in = (in + 1) % BUFFER_SIZE;  
  
        // 表示缓冲区已满  
        sem_post(&full);  
  
        // 模拟数据采集间隔  
        usleep(100000); // 休眠100ms  
    }  
    return NULL;  
}  
  
// 计算任务  
void* computation_task(void* arg) {  
    while (1) {  
        // 等待缓冲区有数据  
        sem_wait(&full);  
  
        // 从缓冲区读取数据  
        int data = buffer[out];  
        printf("Computed data: %d\n", data);  
  
        // 更新输出位置并处理环绕  
        out = (out + 1) % BUFFER_SIZE;  
  
        // 表示缓冲区为空  
        sem_post(&empty);  
  
        // 模拟计算时间  
        usleep(200000); // 休眠200ms  
    }  
    return NULL;  
}  
  
int main() {  
    // 初始化信号量  
    sem_init(&empty, 0, 1); // 初始时缓冲区为空  
    sem_init(&full, 0, 0);  // 初始时缓冲区没有数据  
  
    // 创建线程  
    pthread_t collector_thread, computer_thread;  
    pthread_create(&collector_thread, NULL, data_collection_task, NULL);  
    pthread_create(&computer_thread, NULL, computation_task, NULL);  
  
    // 等待线程结束（这里我们简单地让主线程一直运行，因为数据采集和计算是无限循环）  
    // 实际中，你可能需要其他方式来同步线程的结束  
  
    // 清理资源（在程序结束时）  
    sem_destroy(&empty);  
    sem_destroy(&full);  
  
    // 注意：这里我们并没有真正等待线程结束，因为它们是无限循环的。  
    // 在实际的应用中，你需要有一个机制来安全地结束这些线程。  
  
    return 0;  
}